/**
 * 
 */
package edu.sjtu.seda.threadpool;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import edu.sjtu.seda.event.EventRejectHandler;
import edu.sjtu.seda.event.EventRejectHandlerImpl;
import edu.sjtu.seda.stage.StageWrapper;

/**
 * @author john.zhu
 * 
 */
public class ThreadPoolImpl implements ThreadPool {

	private ExecutorService threadpool;
	private StageWrapper wrapper;
	private volatile int coreThreadPoolSize;

	public ThreadPoolImpl(StageWrapper wrapper,
			BlockingQueue<Runnable> workQueue) {
		this(wrapper, 5, workQueue);
	}
	
	public ThreadPoolImpl(StageWrapper wrapper, int corePoolSize,
			BlockingQueue<Runnable> workQueue){
		this(wrapper,corePoolSize,workQueue,new EventRejectHandlerImpl(wrapper.getStage().getName()));
	}

	public ThreadPoolImpl(StageWrapper wrapper, int corePoolSize,
			BlockingQueue<Runnable> workQueue,EventRejectHandler rejectHandler) {
		this.wrapper = wrapper;
		if (threadpool != null)
			throw new RuntimeException("Threadpool already exists!");
		this.coreThreadPoolSize = corePoolSize;
		threadpool = new ThreadPoolExecutor(coreThreadPoolSize,
				coreThreadPoolSize, 0L, TimeUnit.MILLISECONDS, workQueue,
				rejectHandler);
	}

	@Override
	public void execute(Runnable runner) {
		threadpool.execute(runner);
	}

	@Override
	public void shutdown() {
		threadpool.shutdown();
		try {
			threadpool.awaitTermination(2, TimeUnit.MINUTES);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	@Override
	public boolean isTerminated() {
		return false;
	}

}
